package com.hb.core.oauth2;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: token无效处理
 * @projectName: zhb-frame-build
 * @author: zhouhaizhi
 * @createTime: 2021/8/27 17:44
 * @version:1.0
 */
@Component("resourceAuthExceptionEntryPoint")
@Slf4j
public class ResourceAuthExceptionEntryPoint implements AuthenticationEntryPoint {

    private static final String LEFT_POINT = "(";

    private static final String RIGHT_POINT = ")";

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
        Throwable cause = authException.getCause();
        response.setHeader("Content-Type", "application/json;charset=UTF-8");

        log.warn("---------自定义token异常处理---------,e-->{}", authException);
        try {
            if (cause instanceof OAuth2AccessDeniedException) {
                response.setStatus(HttpStatus.SC_FORBIDDEN);
                response.getWriter().write(buildResult(HttpStatus.SC_FORBIDDEN, fillMessage(
                        getResourceId(cause.getMessage()))));
            } else {
                response.setStatus(HttpStatus.SC_FORBIDDEN);
                response.getWriter().write(buildResult(HttpStatus.SC_UNAUTHORIZED, "Token Error"));
            }
        } catch (IOException e) {
            log.warn("自定义token异常处理出现异常", e);
        }

    }

    private String buildResult(int code, String message) {
        Map<String, Object> result = new HashMap<>();
        result.put("message", message);
        result.put("code", code);
        return JSON.toJSONString(result);
    }

    /*
        从消息中获取resourceId
     */
    private String getResourceId(String errorMessage) {
        if (StringUtils.isEmpty(errorMessage)) {
            return null;
        }
        if (errorMessage.indexOf(LEFT_POINT) <= 0 || errorMessage.indexOf(RIGHT_POINT) <= 0) {
            return null;
        }
        return errorMessage.substring(errorMessage.indexOf(LEFT_POINT) + 1, errorMessage.lastIndexOf(RIGHT_POINT));
    }

    /*
        填充信息
     */
    private String fillMessage(String value) {
        if (StringUtils.isEmpty(value)) {
            return "No Permission";
        }
        return String.format("No Permission", new Object[]{value});

    }
}
